import moment from 'moment'
import { cloneDeep } from 'lodash'
/**
 * @author ZhenYuTsai
 * @description 格式化日期
 * @return {Sting} 格式后的日期
 * @lastEditors ZhenYuTsai
 * @param {[Date,Number]} value 需要格式化的日期Date()类型
 * @param {String} fmt 格式模板，默认'YYYY-MM-DD'
 */
export function formatDate (value, format = 'YYYY-MM-DD') {
  if (value) {
    const date = new Date(value)
    return moment(date).format(format)
  } else {
    return ''
  }
}
/**
 * @author ZhenYuTsai
 * @description 格式化日期时间
 * @return {Sting} 格式后的日期时间
 * @lastEditors ZhenYuTsai
 * @param {[Date,Number]} val 需要格式化的日期Date()类型
 * @param {String} fmt 格式模板，默认'yyyy-MM-dd hh:mm:ss'
 */
export function formatDateTime (value, format = 'YYYY-MM-DD HH:mm:ss') {
  if (value) {
    const date = new Date(value)
    return moment(date).format(format)
  } else {
    return ''
  }
}
/**
 * @author ZhenYuTsai
 * @description 处理金额千分号
 * @return {String} 千分号分隔的值
 * @lastEditors ZhenYuTsai
 * @param {[Number,String]} value
 */
export function formatThousandSeparator (num) {
  // 确保输入是字符串或数字
  num = String(num || 0).replace(/[^0-9.-]/g, '')
  if (num.indexOf('.') === -1) {
    num += '.'
    num = num.slice(0, num.length - 1) // 移除末尾的'.'
  }

  const parts = num.split('.')
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  return parts.join('.')
}
/**
 * @description 判断给定的字符串是否是有效的JSON格式
 * @param str 要检查的字符串
 * @returns 如果字符串是有效的JSON格式，返回true；否则返回false
 */
export function isJSON (str) {
  try {
    JSON.parse(str)
    return true
  } catch (e) {
    return false
  }
}
/**
 * @description 判断给定的值是否是一个普通对象
 * @param value 要检查的值
 * @returns 如果值是普通对象，返回true；否则返回false
 */
export function isObject (value) {
  return Object.prototype.toString.call(value) === '[object Object]'
}
/**
 * @description 判断给定的值是否是一个数组
 * @param value 要检查的值
 * @returns 如果值是数组，返回true；否则返回false
 */
export function isArray (value) {
  return Array.isArray(value)
}
/**
 * @description 判断给定的值是否是一个字符串
 * @param value 要检查的值
 * @returns 如果值是字符串，返回true；否则返回false
 */
export function isString (value) {
  return typeof value === 'string'
}
/**
 * @description 判断给定的值是否不是falsy值（如false、0、""、null、undefined、NaN）且不是空数组或空对象
 * @param value 要检查的值
 * @returns 如果值不是falsy值且不是空数组或空对象，返回true；否则返回false
 */
export function isNotFalsyOrEmpty (value) {
  return value !== false &&
          value !== 0 &&
          value !== '' &&
          value !== null &&
          value !== undefined &&
          !isNaN(value) &&
          !(Array.isArray(value) && value.length === 0) &&
          !(typeof value === 'object' && Object.keys(value).length === 0)
}
/**
 * @description 地址栏传参转换为对象
 * @param {string} url
 * @returns {Object}
 */
export function paramToObject (url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, ' ') +
      '"}'
  )
}
/**
 * @description 对象转换为地址栏传参
 * @param {Object} obj
 * @returns {String}
 */
export function objectToParams (obj) {
  if (obj === null || typeof obj !== 'object') {
    throw new Error('Input must be an object')
  }

  const params = []
  for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
      const value = obj[key]
      if (value !== null && value !== undefined) {
        // 如果值是数组或对象，我们需要递归处理
        if (Array.isArray(value) || typeof value === 'object') {
          // 这里为了简化，我们只处理对象的第一层属性，并且数组会被转换为逗号分隔的字符串
          // 对于更复杂的情况，你可能需要递归调用 objectToParams
          params.push(encodeURIComponent(key) + '=' + encodeURIComponent(JSON.stringify(value)))
        } else {
          params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value.toString()))
        }
      }
    }
  }

  return params.join('&')
}
/**
 * @description 深度拷贝
 * @param {Object} value
 * @returns {Object}
 */
export function DeepCopy (value) {
  return cloneDeep(value)
}
export default {
  formatDate,
  formatDateTime,
  formatThousandSeparator,
  isJSON,
  isString,
  isObject,
  isArray,
  isNotFalsyOrEmpty,
  paramToObject,
  objectToParams,
  DeepCopy
}
